from ZPublisher.HTTPRequest import FileUpload
from cgi import FieldStorage
from StringIO import StringIO
import os.path
import re

# XXX the boundary should be checked to ensure that it does not
# collide with contents of the sample data.
FILE_DATA = """
--12345
Content-Disposition: form-data; name="image"; filename="%s"

%s
--12345--
"""


ENVIRON = {
    'CONTENT_TYPE': 'multipart/form-data; boundary=12345',
    'REQUEST_METHOD': 'POST',
    }



def createFileUpload(sample):
    filename = os.path.basename(sample)
    packagereference = re.compile('package:(.*?):(.*)')
    match = packagereference.match(sample)
    if match:
        packagename = match.group(1)
        filepath = match.group(2)
        packagemodule = None
        exec('import %s as packagemodule' %(packagename))
        packagepath = os.path.dirname(packagemodule.__file__)
        path = os.path.join(packagepath, filepath)
    else:
        import Products
        basepath = os.sep.join(getattr(Products, sample.split(os.sep)[0]).__file__.split(os.sep)[0:-2])
        path = os.path.join(basepath, sample)
    data = FILE_DATA % (filename, open(path).read())
    storage = FieldStorage(fp=StringIO(data), environ=ENVIRON.copy())
    image = storage['image']
    return FileUpload(image)


def checkRequestForSamples(request):
    for key in request.form.keys():
        if key.endswith('__ZELENIUM'):
            name = key[:-len('__ZELENIUM')]
            sample = request.form[key]
            if sample:
                # XXX we are guessing the real file name, we should do
                # something about that. That should be fixable by
                # writing the data into the form.
                request.form[name] = createFileUpload(sample)
                del request.form[key]


def patchPublisher():
    import ZPublisher.HTTPRequest
    originalProcessInputs = ZPublisher.HTTPRequest.HTTPRequest.processInputs
    def processInputs(self):
        originalProcessInputs(self)
        checkRequestForSamples(self)
    ZPublisher.HTTPRequest.HTTPRequest.processInputs = processInputs

patchPublisher()
